using MapsterMapper;
using AiQiuQuan.Sport.Model.Models;
using AiQiuQuan.Sport.Core;
using AiQiuQuan.Sport.WebApi.Entities;
using AiQiuQuan.Sport.WebApi.Repositories;
using Microsoft.EntityFrameworkCore;
using AiQiuQuan.Sport.Model.Enums;
using AiQiuQuan.Sport.WebApi.Core;
using AiQiuQuan.Sport.Core.Tool;
using RedLockNet;

namespace AiQiuQuan.Sport.WebApi.Services.Impl
{
    /// <summary>
    /// 约球管理
    /// </summary>
    public class BallService : IBallService
    {
        private readonly IMapper _mapper;
        private readonly IUnitOfWorkManager _unitOfWorkManager;
        private readonly IBallRepository _ballRepository;
        private readonly IVenueInfoRepository _venueInfoRepository;
        private readonly IBallUserRepository _ballUserRepository;
        private readonly ICurrentInfo _currentInfo;
        private readonly IBaseUserRepository _baseUserRepository;
        private readonly IDistributedLockFactory _distributedLockFactory;
        private readonly IGameOrderRepository _gameOrderRepository;
        private readonly IBaseUserService _baseUserService;
        private readonly IPayOrderRepository _payOrderRepository;
        private readonly IBallEvaluationRepository _ballEvaluationRepository;

        /// <summary>
        /// ctor
        /// </summary>
        public BallService(
            IMapper mapper,
            IUnitOfWorkManager unitOfWorkManager,
            IBallRepository ballRepository,
            IVenueInfoRepository venueInfoRepository,
            IBallUserRepository ballUserRepository,
            ICurrentInfo currentInfo,
            IBaseUserRepository baseUserRepository,
            IDistributedLockFactory distributedLockFactory,
            IGameOrderRepository gameOrderRepository,
            IBaseUserService baseUserService,
            IPayOrderRepository payOrderRepository,
            IBallEvaluationRepository ballEvaluationRepository)
        {
            _mapper = mapper;
            _unitOfWorkManager = unitOfWorkManager;
            _ballRepository = ballRepository;
            _venueInfoRepository = venueInfoRepository;
            _ballUserRepository = ballUserRepository;
            _currentInfo = currentInfo;
            _baseUserRepository = baseUserRepository;
            _distributedLockFactory = distributedLockFactory;
            _gameOrderRepository = gameOrderRepository;
            _baseUserService = baseUserService;
            _payOrderRepository = payOrderRepository;
            _ballEvaluationRepository = ballEvaluationRepository;
        }

        /// <summary>
        /// 查询一条记录
        /// </summary>
        public async Task<BallDto> GetAsync(Guid id)
        {
            var ball = await _ballRepository.FirstOrDefaultAsync(m => m.ID == id);
            var result = _mapper.Map<Ball, BallDto>(ball);
            return result;
        }

        /// <summary>
        /// 约球查询
        /// </summary>
        public async Task<BallDto> QueryAsync(BallQueryDto request)
        {
            var ball = await _ballRepository.FirstOrDefaultAsync(m => m.ID == request.BallId);
            var result = _mapper.Map<Ball, BallDto>(ball);
            if (result != null)
            {
                var joinStateList = request.IsAllUser.GetValueOrDefault() ? null : new List<GameJoinStateEnum> { GameJoinStateEnum.Joining, GameJoinStateEnum.JoinCompleted };
                var limitCount = request.IsPlatform ? 0 : 5;
                result.Distance = DistanceTool.GetDistanceKM(result.Lat, result.Lng, request.Lat, request.Lng);
                result.BallUserList = await GetBallUserListAsync(result.ID, limitCount, joinStateList);
                result.JoinCount = result.BallUserList.Count;
                result.IsCreator = result.UserId == _currentInfo.UserId;
            }

            return result;
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        public async Task<PageResult<BallDto>> PageListAsync(BallPageRequestDto request)
        {
            var queryable = CreatePageQueryable(request);
            var pageResult = await queryable.OrderByDescending(m => m.CreateTime).PageListAsync(request);
            foreach (var item in pageResult.Result)
            {
                item.QueryDate = request.QueryDate.HasValue ? request.QueryDate.Value.Date : item.QueryDate;
                await SetBallExtraInfoAsync(item, request.IsPlatform, request.Lat, request.Lng);
            }

            return pageResult;
        }

        /// <summary>
        /// 获取自己参与的约球列表
        /// </summary>
        public async Task<PageResult<BallDto>> GetMyBallPageListAsync(BallSelfPageRequestDto request)
        {
            var queryable = CreateMyBallPageQueryable(request);
            var pageList = await queryable.OrderByDescending(m => m.CreateTime).PageListAsync(request);
            foreach (var item in pageList.Result)
            {
                await SetBallExtraInfoAsync(item, false, request.Lat, request.Lng);
            }

            return pageList;
        }

        /// <summary>
        /// 新增
        /// </summary>
        public async Task<UnaryResult> AddAsync(BallAddDto model)
        {
            if (!model.IsPlatform)
            {
                model.Type = BallTypeEnum.Once;
            }

            var ball = _mapper.Map<Ball>(model);
            ball.IsPlatform = model.IsPlatform;
            ball.UserId = _currentInfo.UserId;
            ball.State = GameStateEnum.Joining;
            await SetBallBaseInfoAsync(ball);
            await _ballRepository.AddAsync(ball);
            return UnaryResult.Succeed();
        }

        /// <summary>
        /// 修改
        /// </summary>
        public async Task<UnaryResult> UpdateAsync(BallUpdateDto model)
        {
            var ball = await _ballRepository.FirstOrDefaultAsync(m => m.ID == model.ID);
            if (ball == null)
            {
                return UnaryResult.Faild(10, "约球不存在");
            }

            if (ball.VersusType != model.VersusType)
            {
                return UnaryResult.Faild(10, "约球对阵类型禁止修改");
            }

            _mapper.Map(model, ball);
            await SetBallBaseInfoAsync(ball);
            await _ballRepository.UpdateAsync(ball);

            return UnaryResult.Succeed();
        }

        /// <summary>
        /// 修改约球状态
        /// </summary>
        public async Task<UnaryResult> UpdateStateAsync(BallStateUpdateDto request)
        {
            var ball = await _ballRepository.FirstOrDefaultAsync(m => m.ID == request.ID);
            if (ball == null)
            {
                return UnaryResult.Faild(10, "约球不存在");
            }

            if (ball.State == GameStateEnum.Finished || ball.State == GameStateEnum.Cancel)
            {
                return UnaryResult.Faild(10, "约球已结束或取消");
            }

            ball.State = request.State;
            await _ballRepository.UpdateAsync(ball);
            return UnaryResult.Succeed();
        }

        /// <summary>
        /// 删除
        /// </summary>
        public async Task<UnaryResult> DeleteAsync(Guid id)
        {
            await _ballRepository.DeleteAsync(p => p.ID == id);
            return UnaryResult.Succeed();
        }

        /// <summary>
        /// 约球报名
        /// </summary>
        public async Task<UnaryResult<BallJoinResultDto>> JoinAsync(BallUserJoinAddDto request)
        {
            var result = new BallJoinResultDto { BallId = request.BallId };
            var currentUser = await _baseUserRepository.AsNoTracking().FirstOrDefaultAsync(m => m.ID == _currentInfo.UserId);
            if (currentUser == null)
            {
                return UnaryResult.From(10, result, "登录用户不存在");
            }

            await using (var redlock = await _distributedLockFactory.CreateLockAsync(request.BallId.ToString("N"), TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(1)))
            {
                if (!redlock.IsAcquired)
                {
                    return UnaryResult.From(10, result, "报名通道拥挤，稍后重试");
                }

                var ball = await _ballRepository.AsNoTracking().FirstOrDefaultAsync(m => m.ID == request.BallId);
                //验证
                var unaryResult = await ValidJoinAsync(ball, request, result);
                if (unaryResult.Code != 0)
                {
                    return unaryResult;
                }

                //数据整理
                var order = CreateOrder(ball, request, currentUser);
                var ballUserList = new List<BallUser>();
                var businessId = Guid.NewGuid();
                request.UserIdList.ForEach(m =>
                {
                    ballUserList.Add(new BallUser
                    {
                        BallId = ball.ID,
                        BusinessId = businessId,
                        UserId = m,
                        JoinDate = request.JoinDate,
                        JoinState = GameJoinStateEnum.Joining,
                        PayState = PayOrderStateEnum.NotPay,
                        JoinUserId = currentUser.ID,
                        GameOrderId = order.ID,
                    });
                });

                //保存
                using (var uow = _unitOfWorkManager.Begin())
                {
                    await _ballUserRepository.BulkAddAsync(ballUserList);
                    await _gameOrderRepository.AddAsync(order);
                    await uow.CompleteAsync();
                }

                result.BallOrderId = order.ID;
                result.BallOrderNo = order.OrderNo;
            }

            return UnaryResult.Succeed(result);
        }

        /// <summary>
        /// 获取约球用户列表
        /// </summary>
        public async Task<List<BallUserDto>> GetBallUserListAsync(BallUserQueryDto request)
        {
            if (request.IsPlatform)
            {
                return await GetBallUserListAsync(request.BallId);
            }
            else
            {
                var joinStateList = new List<GameJoinStateEnum> { GameJoinStateEnum.Joining, GameJoinStateEnum.JoinCompleted };
                return await GetBallUserListAsync(request.BallId, 0, joinStateList);
            }
        }

        /// <summary>
        /// 通过订单ID获取约球用户列表
        /// </summary>
        /// <param name="orderId">约球订单ID</param>
        public async Task<List<BallUserDto>> GetBallUserListByOrderIdAsync(Guid orderId)
        {
            var queryable = from ballUser in _ballUserRepository.AsNoTracking()
                            join user in _baseUserRepository.AsNoTracking()
                            on ballUser.UserId equals user.ID into userd
                            from user in userd.DefaultIfEmpty()
                            where ballUser.GameOrderId == orderId
                            select new BallUserDto
                            {
                                ID = ballUser.ID,
                                BusinessId = ballUser.BusinessId,
                                UserId = ballUser.UserId,
                                GameOrderId = ballUser.GameOrderId,
                                JoinState = ballUser.JoinState,
                                PayState = ballUser.PayState,
                                JoinDate = ballUser.JoinDate,
                                JoinUserId = ballUser.JoinUserId,
                                UserCode = user.U_Code,
                                UserHeadUrl = user.U_Headportrait,
                                UserName = user.U_RealName ?? user.U_NickName,
                                BallId = ballUser.BallId,
                                CreateTime = ballUser.CreateTime,
                            };
            var list = await queryable.ToListAsync();
            return list;
        }

        /// <summary>
        /// 约球用户评价
        /// </summary>
        public async Task<UnaryResult> EvalulateUserAsync(BallEvaluationAddDto request)
        {
            if (!await _ballRepository.AnyAsync(m => m.ID == request.BallId))
            {
                return UnaryResult.Faild(10, "约球不存在");
            }

            var entities = request.DetailList.Select(m => new BallEvaluation { BallId = request.BallId, UserId = m.UserId, Level = m.Level, AddUserId = _currentInfo.UserId }).ToList();
            var userIdList = entities.Select(m => m.UserId).ToList();
            using (var uow = _unitOfWorkManager.Begin())
            {
                await _ballEvaluationRepository.DeleteAsync(m => m.AddUserId == _currentInfo.UserId && userIdList.Contains(m.UserId));
                await _ballEvaluationRepository.BulkAddAsync(entities);
                await uow.CompleteAsync();
            }

            return UnaryResult.Succeed();
        }

        /// <summary>
        /// 获取约球用户评价
        /// </summary>
        public async Task<List<BallEvaluationDto>> GetBallEvalulationListAsync(BallEvaluationRequestDto request)
        {
            var stateList = new List<GameJoinStateEnum> { GameJoinStateEnum.Joining, GameJoinStateEnum.JoinCompleted };
            var queryable = from ballUser in _ballUserRepository.AsNoTracking()
                            join user in _baseUserRepository.AsNoTracking()
                            on ballUser.UserId equals user.ID
                            where ballUser.BallId == request.BallId && stateList.Contains(ballUser.JoinState)
                            select new BallEvaluationDto
                            {
                                BallId = ballUser.BallId,
                                UserId = ballUser.UserId,
                                UserName = user.U_RealName ?? user.U_NickName,
                                HeadUrl = user.U_Headportrait,
                                Level = null
                            };
            var list = await queryable.ToListAsync();
            if (request.IsNotSelf)
            {
                list = list.Where(m => m.UserId != _currentInfo.UserId).ToList();
            }

            if (list.Any())
            {
                var evalulationList = await _ballEvaluationRepository.Where(m => m.BallId == request.BallId).ToListAsync();
                list.ForEach(m =>
                {
                    var evalution = evalulationList.Where(j => j.UserId == m.UserId).OrderByDescending(m => m.Level).FirstOrDefault();
                    m.Level = evalution?.Level ?? BallEvaluationTypeEnum.UnKnown;
                    m.AddUserId = evalution?.AddUserId;
                    m.CreateTime = evalution?.CreateTime;
                });
            }

            return list;
        }

        #region private methods
        /// <summary>
        /// 约球基础信息设置
        /// </summary>
        private async Task SetBallBaseInfoAsync(Ball ball)
        {
            if (ball.Type == BallTypeEnum.Once)
            {
                ball.EndDate = ball.StartDate;
                ball.WeekDay = ball.StartDate.DayOfWeek;
            }

            var venue = await _venueInfoRepository.AsNoTracking().FirstOrDefaultAsync(m => m.ID == ball.VenueId);
            if (venue != null)
            {
                ball.VenueName = venue.VI_Name;
                ball.ProvinceId = venue.ProvinceID;
                ball.ProvinceName = venue.VI_P_Name;
                ball.CityId = venue.CityID;
                ball.CityName = venue.VI_C_Name;
                ball.Lng = venue.VI_Lng.GetValueOrDefault();
                ball.Lat = venue.VI_Lat.GetValueOrDefault();
            }
        }

        /// <summary>
        /// 约球分页queryable
        /// </summary>
        private IQueryable<BallDto> CreatePageQueryable(BallPageRequestDto request)
        {
            var queryable = _ballRepository.AsNoTracking();

            if (!request.IsPlatform && request.IsManage.HasValue && request.IsManage.Value)
            {
                queryable = queryable.Where(m => m.UserId == _currentInfo.UserId);
            }

            if (request.QueryDate.HasValue)
            {
                var date = request.QueryDate.Value.Date;
                var weekDay = request.QueryDate.Value.DayOfWeek;
                queryable = queryable.Where(m => m.StartDate <= date && m.EndDate >= date && m.WeekDay == weekDay);
            }

            if (!string.IsNullOrWhiteSpace(request.Name))
            {
                queryable = queryable.Where(m => m.Name.Contains(request.Name));
            }

            if (request.State.HasValue && request.State.Value != 0)
            {
                queryable = queryable.Where(m => m.State == request.State.Value);
            }

            if (request.ProvinceId.HasValue && request.CityId.HasValue)
            {
                queryable = queryable.Where(m => m.ProvinceId == request.ProvinceId && m.CityId == request.CityId);
            }
            else if (request.ProvinceId.HasValue && !request.CityId.HasValue)
            {
                queryable = queryable.Where(m => m.ProvinceId == request.ProvinceId);
            }

            return queryable.Select(m => new BallDto
            {
                ID = m.ID,
                Name = m.Name,
                Type = m.Type,
                VenueId = m.VenueId,
                VenueName = m.VenueName,
                SiteName = m.SiteName,
                ProvinceId = m.ProvinceId,
                ProvinceName = m.ProvinceName,
                CityId = m.CityId,
                CityName = m.CityName,
                Lat = m.Lat,
                Lng = m.Lng,
                StartDate = m.StartDate,
                EndDate = m.EndDate,
                StartTime = m.StartTime,
                EndTime = m.EndTime,
                WeekDay = m.WeekDay,
                VersusType = m.VersusType,
                Amount = m.Amount,
                State = m.State,
                Sex = m.Sex,
                StartLevel = m.StartLevel,
                EndLevel = m.EndLevel,
                Remark = m.Remark,
                Host = m.Host,
                Phone = m.Phone,
                Logo = m.Logo,
                UserId = m.UserId,
                IsPlatform = m.IsPlatform,
                CreateTime = m.CreateTime
            });
        }

        /// <summary>
        /// 自己参与约球分页queryable
        /// </summary>
        private IQueryable<BallDto> CreateMyBallPageQueryable(BallSelfPageRequestDto request)
        {
            var stateList = new List<GameJoinStateEnum> { GameJoinStateEnum.Joining, GameJoinStateEnum.JoinCompleted };
            var queryable = from ball in _ballRepository.AsNoTracking()
                            join ballUser in _ballUserRepository.AsNoTracking()
                            on ball.ID equals ballUser.BallId
                            where ballUser.UserId == _currentInfo.UserId && stateList.Contains(ballUser.JoinState)
                            select new BallDto
                            {
                                ID = ball.ID,
                                Name = ball.Name,
                                Type = ball.Type,
                                VenueId = ball.VenueId,
                                VenueName = ball.VenueName,
                                SiteName = ball.SiteName,
                                ProvinceId = ball.ProvinceId,
                                ProvinceName = ball.ProvinceName,
                                CityId = ball.CityId,
                                CityName = ball.CityName,
                                Lat = ball.Lat,
                                Lng = ball.Lng,
                                StartDate = ball.StartDate,
                                EndDate = ball.EndDate,
                                StartTime = ball.StartTime,
                                EndTime = ball.EndTime,
                                WeekDay = ball.WeekDay,
                                VersusType = ball.VersusType,
                                Amount = ball.Amount,
                                State = ball.State,
                                Sex = ball.Sex,
                                StartLevel = ball.StartLevel,
                                EndLevel = ball.EndLevel,
                                Remark = ball.Remark,
                                Host = ball.Host,
                                Phone = ball.Phone,
                                Logo = ball.Logo,
                                UserId = ball.UserId,
                                IsPlatform = ball.IsPlatform,
                                CreateTime = ball.CreateTime,
                                QueryDate = ballUser.JoinDate
                            };
            if (!string.IsNullOrWhiteSpace(request.Name))
            {
                queryable = queryable.Where(m => m.Name.Contains(request.Name));
            }

            if (request.State.HasValue && request.State.Value != 0)
            {
                queryable = queryable.Where(m => m.State == request.State.Value);
            }

            if (request.ProvinceId.HasValue && request.CityId.HasValue)
            {
                queryable = queryable.Where(m => m.ProvinceId == request.ProvinceId && m.CityId == request.CityId);
            }
            else if (request.ProvinceId.HasValue && !request.CityId.HasValue)
            {
                queryable = queryable.Where(m => m.ProvinceId == request.ProvinceId);
            }

            return queryable;
        }

        /// <summary>
        /// 设置约球模型其他数据
        /// </summary>
        private async Task SetBallExtraInfoAsync(BallDto item, bool isPlatform, decimal requestLat, decimal requestLng)
        {
            var joinStateList = new List<GameJoinStateEnum> { GameJoinStateEnum.JoinCompleted, GameJoinStateEnum.Joining };
            if (!isPlatform)
            {
                item.Distance = DistanceTool.GetDistanceKM(item.Lat, item.Lng, requestLat, requestLng);
                item.BallUserList = await GetBallUserListAsync(item.ID, 5, joinStateList);
                item.JoinCount = item.BallUserList.Count;
            }
            else
            {
                item.JoinCount = await _ballUserRepository.CountAsync(m => m.BallId == item.ID && joinStateList.Contains(m.JoinState));
            }
        }

        /// <summary>
        /// 获取约球用户列表
        /// </summary>
        /// <param name="ballId">约球ID</param>
        /// <param name="takeCount">数据获取数量，小于等于0不限制</param>
        /// <param name="joinStateList">报名人状态列表，null或empty查询全部</param>
        private async Task<List<BallUserDto>> GetBallUserListAsync(Guid ballId, int takeCount = 0, List<GameJoinStateEnum> joinStateList = null)
        {
            var paySateList = new List<PayOrderStateEnum> { PayOrderStateEnum.Paid, PayOrderStateEnum.Refunded, PayOrderStateEnum.PartialRefunded };
            var queryable = from ballUser in _ballUserRepository.AsNoTracking()
                            join user in _baseUserRepository.AsNoTracking()
                            on ballUser.UserId equals user.ID into userd
                            from user in userd.DefaultIfEmpty()
                            join user1 in _baseUserRepository.AsNoTracking()
                            on ballUser.JoinUserId equals user1.ID into user1d
                            from user1 in user1d.DefaultIfEmpty()
                            join payorder in _payOrderRepository.AsNoTracking()
                            on ballUser.GameOrderId equals payorder.BusinessId into payorderd
                            from payorder in payorderd.DefaultIfEmpty()
                            where ballUser.BallId == ballId
                            select new BallUserDto
                            {
                                ID = ballUser.ID,
                                BusinessId = ballUser.BusinessId,
                                UserId = ballUser.UserId,
                                GameOrderId = ballUser.GameOrderId,
                                JoinState = ballUser.JoinState,
                                PayState = ballUser.PayState,
                                JoinDate = ballUser.JoinDate,
                                JoinUserId = ballUser.JoinUserId,
                                UserCode = user.U_Code,
                                UserHeadUrl = user.U_Headportrait,
                                UserName = user.U_RealName ?? user.U_NickName,
                                BallId = ballUser.BallId,
                                CreateTime = ballUser.CreateTime,
                                JoinUserCode = user1.U_Code,
                                PayAmount = paySateList.Contains(ballUser.PayState) ? payorder.PayAmount : 0,
                                RefundAmount = paySateList.Contains(ballUser.PayState) ? payorder.RefundAmount : 0
                            };
            if (joinStateList != null && joinStateList.Any())
            {
                queryable = queryable.Where(m => joinStateList.Contains(m.JoinState));
            }

            if (takeCount > 0)
            {
                queryable = queryable.Take(takeCount);
            }

            var list = await queryable.ToListAsync();
            foreach (var item in list)
            {
                item.UserTennisLevel = (await _baseUserService.GetTennisLevelAsync(item.UserId)).LevelName;
            }

            return list.OrderBy(m => m.BusinessId).ToList();
        }

        /// <summary>
        /// 约球报名验证
        /// </summary>
        private async Task<UnaryResult<BallJoinResultDto>> ValidJoinAsync(Ball ball, BallUserJoinAddDto request, BallJoinResultDto result)
        {
            if (ball == null)
            {
                return UnaryResult.From(10, result, "未查询到活动");
            }

            if (ball.State != GameStateEnum.Joining)
            {
                return UnaryResult.From(10, result, "活动非报名中状态");
            }

            if (!await _ballRepository.AnyAsync(m => m.StartDate <= request.JoinDate && m.EndDate >= request.JoinDate && m.WeekDay == request.JoinDate.DayOfWeek))
            {
                return UnaryResult.From(10, result, "当前日期不存在约球");
            }

            var ballUserList = await _ballUserRepository.Where(m => m.BallId == request.BallId).ToListAsync();
            //var joinCount = ballUserList.Where(m => m.JoinState == GameJoinStateEnum.Joining || m.JoinState == GameJoinStateEnum.JoinCompleted).Count();
            if (ballUserList.Any())
            {
                BallUser ballUser = null;
                foreach (var userid in request.UserIdList)
                {
                    ballUser = ballUserList.FirstOrDefault(m => m.UserId == userid);
                    if (ballUser != null)
                    {
                        switch (ballUser.JoinState)
                        {
                            case GameJoinStateEnum.Joining:
                            case GameJoinStateEnum.JoinCompleted:
                                return UnaryResult.From(10, result, $"重复报名");
                            case GameJoinStateEnum.Refused:
                            case GameJoinStateEnum.Cancel:
                            default:
                                return UnaryResult.From(10, result, $"拒绝取消用户不能再次报名");
                        }
                    }
                }
            }

            //if (ball.LimitCount < joinCount + request.UserIdList.Count)
            //{
            //    return UnaryResult.From(10, result, $"活动人数超限，已报名:{joinCount}");
            //}

            return UnaryResult.Succeed(result);
        }

        /// <summary>
        /// 约球业务订单
        /// </summary>
        private GameOrder CreateOrder(Ball ball, BallUserJoinAddDto request, BaseUser user)
        {
            return new GameOrder
            {
                ID = Guid.NewGuid(),
                Name = ball.Name,
                BusinessId = ball.ID,
                BusinessType = BusinessTypeEnum.Ball,
                OrderNo = Tool.BuildPayOrderNo(BusinessTypeEnum.Ball),
                GameDate = request.JoinDate,
                StartTime = ball.StartTime,
                EndTime = ball.EndTime,
                Address = ball.VenueName,
                PayType = PayTypeEnum.None,
                State = GameOrderStateEnum.NotPay,
                JoinCount = request.UserIdList.Count,
                Price = ball.Amount,
                OrderAmount = request.UserIdList.Count * ball.Amount,
                PayAmount = request.UserIdList.Count * ball.Amount,
                Bonus = 0,
                BonusAmount = 0,
                CouponId = null,
                CouponAmount = 0,
                Remark = $"{ball.Name}报名:{user.U_RealName ?? user.U_NickName}",
                RefundAmount = 0,
                RefundRemark = null,
                UserId = user.ID,
                Mobile = user.U_PhoneNum,
                UserName = user.U_RealName ?? user.U_NickName
            };
        }
        #endregion
    }
}
